Chapter 2, Section 2, Integers 1. Signed and unsigned 4-bit arithmetic 1. 16-hour clock face labeled 0000 to 1111. 2. To add one, move hand clockwise one hour. 3. To subtract one, move hand counterclockwase one hour. 4. If you advance hand 16 hours, end up where you started. There must be an error point because X + 16 is not equal to x. Unsigned Arithmetic Signed Arithmetic error \ \ 0000=0 0000=0 \ o o 15=1111 o o 0001=1 -1=1111 o o 0001=1 ^ ^ 14=1110 o | o 0010=2 -2=1110 o | o 0010=2 | | 13=1101 o | o 0011=3 -3=1101 o | o 0011=3 | | | | 12=1100 o o o 0100=4 -4=1100 o o o 0100=4 11=1011 o o 0101=5 -5=1011 o o 0101=5 10=1010 o o 0110=6 -6=1010 o o 0110=6 9=1001 o o 0111=7 -7=1001 o o 0111=7 o o \ 1000=8 1000=-8 \ \ error 2. 4-bit signed magnitude, 1's complement and 2's complement binary numbers 2's 1's signed binary unsigned complement complement magnitude 0000 0 0 0 0 0001 1 1 1 1 0010 2 2 2 2 0011 3 3 3 3 0100 4 4 4 4 0101 5 5 5 5 0110 6 6 6 6 0111 7 7 7 7 1000 8 -8 -7 -0 1001 9 -7 -6 -1 1010 10 -6 -5 -2 1011 11 -5 -4 -3 1100 12 -4 -3 -4 1101 13 -3 -2 -5 1110 14 -2 -1 -6 1111 15 -1 -0 -7 3. 8-bit signed and unsigned numbers unix>int8.sh #include #define DELTA 8 void printchar(unsigned char); main() { unsigned char x; printf("\n Unsigned binary Signed\n\n"); for (x = 0; x <= DELTA; x++) printchar(x); printf("\n"); for (x = 128-DELTA; x <= 128+DELTA; x++) printchar(x); printf("\n"); for (x = 255-DELTA; x > 0; x++) printchar(x); printf("\n"); } void printchar(unsigned char x) { unsigned char i; printf("%5u %2.2x ", x, x); for (i = 128; i > 0; i>>=1) printf("%c", (i & x ? '1' : '0')); printf(" %2.2x %4d \n", x, (signed char) x); } Unsigned binary Signed 0 00 00000000 00 0 1 01 00000001 01 1 2 02 00000010 02 2 3 03 00000011 03 3 4 04 00000100 04 4 5 05 00000101 05 5 6 06 00000110 06 6 7 07 00000111 07 7 8 08 00001000 08 8 120 78 01111000 78 120 121 79 01111001 79 121 122 7a 01111010 7a 122 123 7b 01111011 7b 123 124 7c 01111100 7c 124 125 7d 01111101 7d 125 126 7e 01111110 7e 126 127 7f 01111111 7f 127 128 80 10000000 80 -128 129 81 10000001 81 -127 130 82 10000010 82 -126 131 83 10000011 83 -125 132 84 10000100 84 -124 133 85 10000101 85 -123 134 86 10000110 86 -122 135 87 10000111 87 -121 136 88 10001000 88 -120 247 f7 11110111 f7 -9 248 f8 11111000 f8 -8 249 f9 11111001 f9 -7 250 fa 11111010 fa -6 251 fb 11111011 fb -5 252 fc 11111100 fc -4 253 fd 11111101 fd -3 254 fe 11111110 fe -2 255 ff 11111111 ff -1 unix> 4. 16-bit signed and unsigned numbers unix>int16.sh #include #define DELTA 8 void printshort(unsigned short); main() { unsigned short x; printf(" Unsigned Signed\n"); printf(" dec Hex binary Hex dec\n\n"); for (x = 0; x <= DELTA; x++) printshort(x); printf("\n"); for (x = 32768-DELTA; x <= 32768+DELTA; x++) printshort(x); printf("\n"); for (x = 65535-DELTA; x > 0; x++) printshort(x); printf("\n"); } void printshort(unsigned short x) { unsigned short i; printf(" %5lu %4.4x ", x, x); for (i = 32768; i > 0; i>>=1) printf("%c", (i & x ? '1' : '0')); printf(" %4.4x %6ld \n", x, (signed short) x); } Unsigned Signed dec Hex binary Hex dec 0 0000 0000000000000000 0000 0 1 0001 0000000000000001 0001 1 2 0002 0000000000000010 0002 2 3 0003 0000000000000011 0003 3 4 0004 0000000000000100 0004 4 5 0005 0000000000000101 0005 5 6 0006 0000000000000110 0006 6 7 0007 0000000000000111 0007 7 8 0008 0000000000001000 0008 8 32760 7ff8 0111111111111000 7ff8 32760 32761 7ff9 0111111111111001 7ff9 32761 32762 7ffa 0111111111111010 7ffa 32762 32763 7ffb 0111111111111011 7ffb 32763 32764 7ffc 0111111111111100 7ffc 32764 32765 7ffd 0111111111111101 7ffd 32765 32766 7ffe 0111111111111110 7ffe 32766 32767 7fff 0111111111111111 7fff 32767 32768 8000 1000000000000000 8000 -32768 32769 8001 1000000000000001 8001 -32767 32770 8002 1000000000000010 8002 -32766 32771 8003 1000000000000011 8003 -32765 32772 8004 1000000000000100 8004 -32764 32773 8005 1000000000000101 8005 -32763 32774 8006 1000000000000110 8006 -32762 32775 8007 1000000000000111 8007 -32761 32776 8008 1000000000001000 8008 -32760 65527 fff7 1111111111110111 fff7 -9 65528 fff8 1111111111111000 fff8 -8 65529 fff9 1111111111111001 fff9 -7 65530 fffa 1111111111111010 fffa -6 65531 fffb 1111111111111011 fffb -5 65532 fffc 1111111111111100 fffc -4 65533 fffd 1111111111111101 fffd -3 65534 fffe 1111111111111110 fffe -2 65535 ffff 1111111111111111 ffff -1 unix> 5. 32-bit signed and unsigned numbers #include #define DELTA 8 void printint(unsigned long); main() { unsigned long x; printf("\n Unsign Dec Hex binary Hex Signed Dec\n\n"); for (x = 0; x <= DELTA; x++) printint(x); printf("\n"); for (x = (1ul << 31) - DELTA; x <= (1ul << 31) + DELTA; x++) printint(x); printf("\n"); for (x = 0ul - DELTA; x > 0; x++) printint(x); printf("\n"); } void printint(unsigned long x) { unsigned long i; printf(" %10lu %8.8x ", x, x); for (i = 1ul<<31; i > 0; i>>=1) printf("%c", (i & x ? '1' : '0')); printf(" %8.8x %11ld \n", x, (signed long) x); } Unsign Dec Hex binary Hex Signed Dec 0 00000000 00000000000000000000000000000000 00000000 0 1 00000001 00000000000000000000000000000001 00000001 1 2 00000002 00000000000000000000000000000010 00000002 2 3 00000003 00000000000000000000000000000011 00000003 3 4 00000004 00000000000000000000000000000100 00000004 4 5 00000005 00000000000000000000000000000101 00000005 5 6 00000006 00000000000000000000000000000110 00000006 6 7 00000007 00000000000000000000000000000111 00000007 7 8 00000008 00000000000000000000000000001000 00000008 8 2147483640 7ffffff8 01111111111111111111111111111000 7ffffff8 2147483640 2147483641 7ffffff9 01111111111111111111111111111001 7ffffff9 2147483641 2147483642 7ffffffa 01111111111111111111111111111010 7ffffffa 2147483642 2147483643 7ffffffb 01111111111111111111111111111011 7ffffffb 2147483643 2147483644 7ffffffc 01111111111111111111111111111100 7ffffffc 2147483644 2147483645 7ffffffd 01111111111111111111111111111101 7ffffffd 2147483645 2147483646 7ffffffe 01111111111111111111111111111110 7ffffffe 2147483646 2147483647 7fffffff 01111111111111111111111111111111 7fffffff 2147483647 2147483648 80000000 10000000000000000000000000000000 80000000 -2147483648 2147483649 80000001 10000000000000000000000000000001 80000001 -2147483647 2147483650 80000002 10000000000000000000000000000010 80000002 -2147483646 2147483651 80000003 10000000000000000000000000000011 80000003 -2147483645 2147483652 80000004 10000000000000000000000000000100 80000004 -2147483644 2147483653 80000005 10000000000000000000000000000101 80000005 -2147483643 2147483654 80000006 10000000000000000000000000000110 80000006 -2147483642 2147483655 80000007 10000000000000000000000000000111 80000007 -2147483641 2147483656 80000008 10000000000000000000000000001000 80000008 -2147483640 4294967288 fffffff8 11111111111111111111111111111000 fffffff8 -8 4294967289 fffffff9 11111111111111111111111111111001 fffffff9 -7 4294967290 fffffffa 11111111111111111111111111111010 fffffffa -6 4294967291 fffffffb 11111111111111111111111111111011 fffffffb -5 4294967292 fffffffc 11111111111111111111111111111100 fffffffc -4 4294967293 fffffffd 11111111111111111111111111111101 fffffffd -3 4294967294 fffffffe 11111111111111111111111111111110 fffffffe -2 4294967295 ffffffff 11111111111111111111111111111111 ffffffff -1 6. Conversions - short, long, signed, unsigned USE A CAST WHEN INFORMATION MIGHT BE LOST DURING A CONVERSION TO SHOW THAT YOU HAVE THOUGHT ABOUT THE POSSIBLE INFORMATION LOSS unix> more p56.c #include main() { short mys = -30000; unsigned short myus = 60000; long myl = 2000000000L; unsigned long myul = 4000000000UL; printf(" short ushort long ulong\n"); mys = -30000; myus = mys; myl = mys; myul = mys; printf("%8i %8u %14i %14u \n", mys, myus, myl, myul); myus = 60000; mys = myus; myl = myus; myul = myus; printf("%8i %8u %14i %14u \n", mys, myus, myl, myul); myl = -2000000000L; mys = myl; myus = myl; myul = myl; printf("%8i %8u %14i %14u \n", mys, myus, myl, myul); myul = 4000000000UL; mys = myul; myus = myul; myl = myul; printf("%8i %8u %14i %14u \n", mys, myus, myl, myul); } unix> gcc p56.c unix> ./a.out short ushort long ulong -30000 35536 -30000 4294937296 -5536 60000 60000 60000 27648 27648 -2000000000 2294967296 10240 10240 -294967296 4000000000 unix> 7. Minimum and maximum values - extracted from /usr/include/limits.h /* These assume 8-bit `char's, 16-bit `short int's, and 32-bit `int's and `long int's. */ /* Number of bits in a `char'. */ # define CHAR_BIT 8 /* Minimum and maximum values a `signed char' can hold. */ # define SCHAR_MIN (-128) # define SCHAR_MAX 127 /* Maximum value an `unsigned char' can hold. (Minimum is 0.) */ # define UCHAR_MAX 255 /* Minimum and maximum values a `signed short int' can hold. */ # define SHRT_MIN (-32768) # define SHRT_MAX 32767 /* Maximum value an `unsigned short int' can hold. (Minimum is 0.) */ # define USHRT_MAX 65535 /* Minimum and maximum values a `signed int' can hold. */ # define INT_MIN (-INT_MAX - 1) # define INT_MAX 2147483647 /* Maximum value an `unsigned int' can hold. (Minimum is 0.) */ # define UINT_MAX 4294967295U /* Minimum and maximum values a `signed long int' can hold. */ # define LONG_MAX 2147483647L # define LONG_MIN (-LONG_MAX - 1L) 7. Conversions